%{
    #include "syntax.tab.h"
    #include "syntaxtree.h"
    int yycolumn = 1;
    #define YY_USER_ACTION \
        yylloc.first_line = yylloc.last_line = yylineno; \
        yylloc.first_column = yycolumn; \
        yylloc.last_column = yycolumn + yyleng - 1; \
        yycolumn += yyleng;
    extern int myerror;
%}

COMMENT  \/\*([^\/]|[^\*]\/)*\*\/
decimal  [1-9][0-9]{0,31}|[0-9]
octal    0[0-7]{1,31}
hex      0[xX][0-9a-fA-F]{1,30}
FLOAT    ([0-9]+\.[0-9]+)|(([0-9]*\.[0-9]+|[0-9]+\.)[Ee](\+|-)?[0-9]+)
ID       [a-zA-Z_][a-zA-Z0-9_]{0,31}
SEMI     ;
COMMA    ,
ASSIGNOP =
RELOP    >|<|>=|<=|==|!=
PLUS     \+
MINUS    -
STAR     \*
DIV      \/
AND      &&
OR       \|\|
DOT      \.
NOT      !
TYPE     int|float
LP       \(
RP       \)
LB       \[
RB       \]
LC       \{
RC       \}
STRUCT   struct
RETURN   return
IF       if
ELSE     else
WHILE    while
%option yylineno
%%
\n          {yycolumn=1;}
" "         {/*do nothing*/}
"//"        {   char c = input();
                while(c!='\n') c = input();
            }
{COMMENT}   {/*do nothing*/}
{SEMI}      {   
                yylval = (YYSTYPE)createNode(_SEMI,0,yylineno,NULL);
                return SEMI;
            }
{COMMA}     {   
                yylval = (YYSTYPE)createNode(_COMMA,0,yylineno,NULL);
                return COMMA;
            }
{ASSIGNOP}  {   
                yylval = (YYSTYPE)createNode(_ASSIGNOP,0,yylineno,NULL);
                return ASSIGNOP;
            }
{RELOP}     {   
                yylval = (YYSTYPE)createNode(_RELOP,0,yylineno,NULL);
                return RELOP;
            }
{PLUS}      {   
                yylval = (YYSTYPE)createNode(_PLUS,0,yylineno,NULL);
                return PLUS;
            }
{MINUS}     {   
                yylval = (YYSTYPE)createNode(_MINUS,0,yylineno,NULL);
                return MINUS;
            }
{STAR}      {   
                yylval = (YYSTYPE)createNode(_STAR,0,yylineno,NULL);
                return STAR;
            }
{DIV}       {   
                yylval = (YYSTYPE)createNode(_DIV,0,yylineno,NULL);
                return DIV;
            }
{AND}       {   
                yylval = (YYSTYPE)createNode(_AND,0,yylineno,NULL);
                return AND;
            }
{OR}        {   
                yylval = (YYSTYPE)createNode(_OR,0,yylineno,NULL);
                return OR;
            }
{DOT}       {   
                yylval = (YYSTYPE)createNode(_DOT,0,yylineno,NULL);
                return DOT;
            }
{NOT}       {   
                yylval = (YYSTYPE)createNode(_NOT,0,yylineno,NULL);
                return NOT;
            }
{LP}        {   
                yylval = (YYSTYPE)createNode(_LP,0,yylineno,NULL);
                return LP;
            }
{RP}        {   
                yylval = (YYSTYPE)createNode(_RP,0,yylineno,NULL);
                return RP;
            }
{LB}        {   
                yylval = (YYSTYPE)createNode(_LB,0,yylineno,NULL);
                return LB;
            }
{RB}        {   
                yylval = (YYSTYPE)createNode(_RB,0,yylineno,NULL);
                return RB;
            }
{LC}        {   
                yylval = (YYSTYPE)createNode(_LC,0,yylineno,NULL);
                return LC;
            }
{RC}        {   
                yylval = (YYSTYPE)createNode(_RC,0,yylineno,NULL);
                return RC;
            }
{STRUCT}    {   
                yylval = (YYSTYPE)createNode(_STRUCT,0,yylineno,NULL);
                return STRUCT;
            }
{RETURN}    {   
                yylval = (YYSTYPE)createNode(_RETURN,0,yylineno,NULL);
                return RETURN;
            }
{IF}        {   
                yylval = (YYSTYPE)createNode(_IF,0,yylineno,NULL);
                return IF;
            }
{ELSE}      {   
                yylval = (YYSTYPE)createNode(_ELSE,0,yylineno,NULL);
                return ELSE;
            }
{WHILE}     {   
                yylval = (YYSTYPE)createNode(_WHILE,0,yylineno,NULL);
                return WHILE;
            }
{TYPE}      {   
                char* p = (char*)malloc(strlen(yytext));
                strcpy(p,yytext);
                yylval = (YYSTYPE)createNode(_TYPE,0,yylineno,(union data_type*)p);
                return TYPE;
            }
{ID}        {
                char* p = (char*)malloc(strlen(yytext));
                strcpy(p,yytext);
                yylval = (YYSTYPE)createNode(_ID,0,yylineno,(union data_type*)p);
                return ID;
            }
{decimal}   {
                int* p = (int*)malloc(sizeof(int));
                *p = atoi(yytext);
                yylval = (YYSTYPE)createNode(_INT,0,yylineno,(union data_type*)p);
                return INT;
            }
{octal}     {   //octal to decimal
                int* p = (int*)malloc(sizeof(int));
                *p = OctToDec();
                yylval = (YYSTYPE)createNode(_INT,0,yylineno,(union data_type*)p);
                return INT;
            }
{hex}       {   //hex to decimal 
                int* p = (int*)malloc(sizeof(int));
                *p = HexToDec();
                yylval = (YYSTYPE)createNode(_INT,0,yylineno,(union data_type*)p);
                return INT;
            }
{FLOAT}     {   
                float* p = (float*)malloc(sizeof(float));
                *p = (float)atof(yytext);
                yylval = (YYSTYPE)createNode(_FLOAT,0,yylineno,(union data_type*)p);
                return FLOAT;
            }
.           {myerror = 1;printf("Error type A at line %d: Mysterious character \"%s\"\n",yylineno,yytext);}
%%

int OctToDec(){
    char* p = yytext;
    char tmp = *(++p);
    int res = 0;
    while(tmp!='\0'){
        res = (res + tmp - '0')*8;
        tmp = *(++p);
    }
    return res = res/8;
}

int HexToDec(){
    char* p = yytext;
    p = p + 2;
    char tmp = *p;
    int res = 0;
    while(tmp!='\0'){
        if( tmp >= 'A' && tmp <='F')
            res = (res + tmp - 'A' + 10)*16;
        else if (tmp >= 'a' && tmp <='f')
            res = (res + tmp - 'a' + 10)*16;
        else 
        
            res = (res + tmp - '0')*16;
        tmp = *(++p);
    }
    return res = res/16;
}
